package model;

import junit.framework.TestCase;

import java.sql.SQLException;
import java.util.ArrayList;
import java.sql.Date;
import java.util.List;

/**
 * This class creates the Query Test. It test the database by creating users
 * john1, john2, john3, rob, bob, steve1, steve2, daniel, yolanda, and stewart.
 * 
 * @author Josh Harris and Daranhdara Hun
 * @version 1.0
 */

public class MyQueryTest extends TestCase {

	private MyQuery query;

	private User john1, john2, john3, rob, bob, steve1, steve2, daniel,
			yolonda, stewart;

	private final boolean[] arr = { true, false, false, false };

	/**
	 * This constructor creates the new users, dates, and sets the birth dates.
	 * It then adds the users to the database.
	 */
	public void setUp() {
		
		try {
			super.setUp();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		query = new MyQuery();
		john1 = new User("aaa", "aaa", arr, 1, "john");
		final Date date = new Date(1111111111);
		john1.setBirthDate(date);

		john2 = new User("bbb", "bbb", arr, 2, "john");
		john2.setBirthDate(date);

		john3 = new User("ccc", "ccc", arr, 3, "john");
		john3.setBirthDate(date);

		rob = new User("ddd", "ddd", arr, 4, "rob");
		rob.setBirthDate(date);

		bob = new User("eee", "eee", arr, 5, "bob");
		bob.setBirthDate(date);

		steve1 = new User("fff", "fff", arr, 6, "steve");
		steve1.setBirthDate(date);

		steve2 = new User("ggg", "ggg", arr, 7, "steve");
		steve2.setBirthDate(date);

		daniel = new User("hhh", "hhh", arr, 8, "daniel");
		daniel.setBirthDate(date);

		yolonda = new User("iii", "iii", arr, 9, "yolonda");
		yolonda.setBirthDate(date);

		stewart = new User("jjj", "jjj", arr, 10, "stewart");
		stewart.setBirthDate(date);

		query.addUser(john1);
		query.addUser(john2);
		query.addUser(john3);
		query.addUser(rob);
		query.addUser(bob);
		query.addUser(steve1);
		query.addUser(steve2);
		query.addUser(daniel);
		query.addUser(yolonda);
		query.addUser(stewart);
		
	}

	/**
	 * This method sets all the users to null in the database.
	 */
	public void tearDown() {
		try {
			super.tearDown();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		query = null;
		john1 = null;
		john2 = null;
		john3 = null;
		rob = null;
		bob = null;
		steve1 = null;
		steve2 = null;
		daniel = null;
		yolonda = null;
		stewart = null;
	}

	/**
	 * This method is a test search to search the users by name. It uses try and
	 * catch blocks for all the different possible things that could happen.
	 */
	public void testSearchUserByName() {
		List<User> arr = new ArrayList<User>();
		try{
			arr = query.searchUserByName("John"); 
			
		}catch(Exception e){
			e.printStackTrace();
		}
		assertNotNull("searchUserByName() returns null", arr);
		assertTrue("Less then 3 users were found when searching " +
				"for john", arr.size() > 2);
		assertTrue("More then 3 users were found when searching " +
				"for john", arr.size() < 4);

		try{
			arr = query.searchUserByName("steve");
		}catch(Exception e){
			e.printStackTrace();
		}
		assertNotNull("searchUserByName() returns null", arr);
		assertTrue("Less then 2 users were found when searching " +
				"for steve", arr.size() > 1);
		assertTrue("More then 2 users were found when searching " +
				"for steve", arr.size() < 3);
		try{
			arr = query.searchUserByName("yolonda");
		}catch(Exception e){
			e.printStackTrace();
		}
		assertNotNull("searchUserByName() returns null", arr);
		assertTrue("0 users were found when searching for " +
				"yolonda", arr.size() > 0);
		assertTrue("more then 1 user was found while searching " +
				"for yolonda", arr.size() < 2);
		
		try{
			arr = query.searchUserByName("batman");
		}catch(Exception e){
			e.printStackTrace();
		}
		assertNotNull("searchUserByName() returns null", arr);
		assertTrue("a user was found when searching for Batman which " +
				"is not in the Database", arr.size() == 0);
		
	}

	/**
	 * This method deletes the users and uses try/catch blocks in case something
	 * else happens.
	 */
	public void testDeleteUser() {
		try {
			assertTrue("deletion of user returns false", query.deleteUser(10));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			
			assertTrue("deletion of fake user returned true",
					!query.deleteUser(111111111));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * This method tests the authentication of the user. It also uses the
	 * try/catch statements for anything that could happen.
	 */
	public void testAuthenticateUser() {
		try {
			assertNotNull("authentication of real user with correct "
					+ "username and password returned false",
					query.authenticateUser("aaa", "aaa"));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			assertNotNull("authentication of real user with incorrect "
					+ "password returned true",
					query.authenticateUser("eee", "fed"));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			assertNotNull(
					"authentication of a user not in the system returned "
							+ "true", query.authenticateUser("gha", "gha"));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * This class loads users into the system and uses the try/catch statements
	 * to catch potential mistakes.
	 */
	public void testLoadUser() {
		try {
			assertNotNull(
					"null returned when loading a user that should be in "
							+ "the database", query.loadUser(9));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}

		try {
			assertNull("null not returned when loading a user that should not "
					+ "be in the database", query.loadUser(222222222));
		} catch (SQLException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
